package android.slc.appbase.ui.vd;


import android.slc.appbase.ui.utils.magicindicator.TabCommonNavigatorAdapter;
import android.slc.appbase.ui.utils.magicindicator.ViewPager2Helper;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Lifecycle;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;

import com.blankj.utilcode.util.ArrayUtils;
import com.blankj.utilcode.util.CollectionUtils;
import com.blankj.utilcode.util.StringUtils;

import net.lucode.hackware.magicindicator.MagicIndicator;
import net.lucode.hackware.magicindicator.abs.IPagerNavigator;
import net.lucode.hackware.magicindicator.buildins.commonnavigator.CommonNavigator;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MagicIndicatorViewDelegate {
    private final MagicIndicator tabLayout;
    private final ViewPager2 viewPager2;
    private final FragmentStateAdapter fragmentStateAdapter;
    private final IPagerNavigator pagerNavigator;
    private final List<String> tabTitles;

    private static List<String> tabRes2Str(int... resId) {
        List<String> tabStrList = new ArrayList<>();
        ArrayUtils.forAllDo(resId, (ArrayUtils.Closure<Integer>) (index, item) -> tabStrList.add(StringUtils.getString(item)));
        return tabStrList;
    }

    public MagicIndicatorViewDelegate(@NonNull MagicIndicator tabLayout,
                                      @NonNull ViewPager2 viewPager2,
                                      @NonNull FragmentActivity fragmentActivity,
                                      IPagerNavigator pagerNavigator,
                                      @NonNull List<Fragment> fragmentList,
                                      @NonNull String... tabTitles) {
        this(tabLayout, viewPager2, fragmentActivity, pagerNavigator, fragmentList, Arrays.asList(tabTitles));
    }

    public MagicIndicatorViewDelegate(@NonNull MagicIndicator tabLayout,
                                      @NonNull ViewPager2 viewPager2,
                                      @NonNull FragmentActivity fragmentActivity,
                                      IPagerNavigator pagerNavigator,
                                      @NonNull List<Fragment> fragmentList,
                                      @NonNull int... tabResTitles) {
        this(tabLayout, viewPager2, fragmentActivity, pagerNavigator, fragmentList, tabRes2Str(tabResTitles));
    }

    public MagicIndicatorViewDelegate(@NonNull MagicIndicator tabLayout,
                                      @NonNull ViewPager2 viewPager2,
                                      @NonNull FragmentActivity fragmentActivity,
                                      IPagerNavigator pagerNavigator,
                                      @NonNull List<Fragment> fragmentList,
                                      @NonNull List<String> tabTitles) {
        this(tabLayout, viewPager2, MyFragmentStateAdapter.getInstance(fragmentActivity, fragmentList), pagerNavigator, tabTitles);
    }

    public MagicIndicatorViewDelegate(@NonNull MagicIndicator tabLayout,
                                      @NonNull ViewPager2 viewPager2,
                                      @NonNull Fragment fragment,
                                      IPagerNavigator pagerNavigator,
                                      @NonNull List<Fragment> fragmentList,
                                      @NonNull String... tabTitles) {
        this(tabLayout, viewPager2, fragment, pagerNavigator, fragmentList, Arrays.asList(tabTitles));
    }

    public MagicIndicatorViewDelegate(@NonNull MagicIndicator tabLayout,
                                      @NonNull ViewPager2 viewPager2,
                                      @NonNull Fragment fragment,
                                      IPagerNavigator pagerNavigator,
                                      @NonNull List<Fragment> fragmentList,
                                      @NonNull int... tabResTitles) {
        this(tabLayout, viewPager2, fragment, pagerNavigator, fragmentList, tabRes2Str(tabResTitles));
    }

    public MagicIndicatorViewDelegate(@NonNull MagicIndicator tabLayout,
                                      @NonNull ViewPager2 viewPager2,
                                      @NonNull Fragment fragment,
                                      IPagerNavigator pagerNavigator,
                                      @NonNull List<Fragment> fragmentList,
                                      @NonNull List<String> tabTitles) {
        this(tabLayout, viewPager2, MyFragmentStateAdapter.getInstance(fragment, fragmentList), pagerNavigator, tabTitles);
    }

    public MagicIndicatorViewDelegate(@NonNull MagicIndicator tabLayout,
                                      @NonNull ViewPager2 viewPager2,
                                      @NonNull FragmentStateAdapter fragmentStateAdapter,
                                      IPagerNavigator pagerNavigator,
                                      @NonNull String... tabTitles) {
        this(tabLayout, viewPager2, fragmentStateAdapter, pagerNavigator, Arrays.asList(tabTitles));
    }

    public MagicIndicatorViewDelegate(@NonNull MagicIndicator tabLayout,
                                      @NonNull ViewPager2 viewPager2,
                                      @NonNull FragmentStateAdapter fragmentStateAdapter,
                                      IPagerNavigator pagerNavigator,
                                      @NonNull int... tabResTitles) {
        this(tabLayout, viewPager2, fragmentStateAdapter, pagerNavigator, tabRes2Str(tabResTitles));
    }

    public MagicIndicatorViewDelegate(@NonNull MagicIndicator tabLayout,
                                      @NonNull ViewPager2 viewPager2,
                                      @NonNull FragmentStateAdapter fragmentStateAdapter,
                                      IPagerNavigator pagerNavigator,
                                      @NonNull List<String> tabTitles) {
        if (fragmentStateAdapter.getItemCount() != CollectionUtils.size(tabTitles)) {
            throw new IllegalStateException("fragmentList 和 tabTitles 长度不一样");
        }
        this.tabLayout = tabLayout;
        this.viewPager2 = viewPager2;
        this.fragmentStateAdapter = fragmentStateAdapter;
        this.pagerNavigator = pagerNavigator;
        this.tabTitles = tabTitles;
    }

    public void attach() {
        viewPager2.setAdapter(fragmentStateAdapter);
        tabLayout.setNavigator(pagerNavigator == null ? getDefPagerNavigator() : pagerNavigator);
        ViewPager2Helper.bind(tabLayout, viewPager2);
    }

    protected IPagerNavigator getDefPagerNavigator() {
        CommonNavigator commonNavigator = new CommonNavigator(this.tabLayout.getContext());
        commonNavigator.setAdapter(new TabCommonNavigatorAdapter() {
            @Override
            protected List<String> getTabTitles() {
                return MagicIndicatorViewDelegate.this.tabTitles;
            }

            @Override
            protected ViewPager2 getViewPager() {
                return viewPager2;
            }
        });
        commonNavigator.setAdjustMode(true);
        return commonNavigator;
    }

    private static class MyFragmentStateAdapter extends FragmentStateAdapter {
        private List<Fragment> fragmentList;

        public static MyFragmentStateAdapter getInstance(@NonNull FragmentActivity fragmentActivity, List<Fragment> fragmentList) {
            MyFragmentStateAdapter myFragmentStateAdapter = new MyFragmentStateAdapter(fragmentActivity);
            myFragmentStateAdapter.setFragmentList(
                    fragmentList
            );
            return myFragmentStateAdapter;
        }

        public static MyFragmentStateAdapter getInstance(@NonNull Fragment fragment, List<Fragment> fragmentList) {
            MyFragmentStateAdapter myFragmentStateAdapter = new MyFragmentStateAdapter(fragment);
            myFragmentStateAdapter.setFragmentList(
                    fragmentList
            );
            return myFragmentStateAdapter;
        }

        public static MyFragmentStateAdapter getInstance(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle, List<Fragment> fragmentList) {
            MyFragmentStateAdapter myFragmentStateAdapter = new MyFragmentStateAdapter(fragmentManager, lifecycle);
            myFragmentStateAdapter.setFragmentList(
                    fragmentList
            );
            return myFragmentStateAdapter;
        }

        public MyFragmentStateAdapter(@NonNull FragmentActivity fragmentActivity) {
            super(fragmentActivity);
        }

        public MyFragmentStateAdapter(@NonNull Fragment fragment) {
            super(fragment);
        }

        public MyFragmentStateAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
            super(fragmentManager, lifecycle);
        }

        public void setFragmentList(List<Fragment> fragmentList) {
            this.fragmentList = fragmentList;
        }

        @NonNull
        @Override
        public Fragment createFragment(int position) {
            return this.fragmentList.get(position);
        }

        @Override
        public int getItemCount() {
            return this.fragmentList.size();
        }
    }
}
